﻿using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using LinFu.IoC.Configuration;

namespace CoreEx.ServiceModel.Implementation
{
    [Implements(typeof(IInitializer<ServiceHost>), ServiceName = "ServiceMetadataBehaviorInitializer")]
    public class ServiceMetadataBehaviorInitializer : InitializerBase<ServiceHost>
    {
        public override void Initialize(ServiceHost serviceHost)
        {
            AddServiceMetadataBehavior(serviceHost);
            AddMexEndpoints(serviceHost);
        }

        private static void AddServiceMetadataBehavior(ServiceHost serviceHost)
        {
            var metadataBehavior = serviceHost.Description.Behaviors.Find<ServiceMetadataBehavior>();
            
            if (metadataBehavior != null) return;
            
            metadataBehavior = new ServiceMetadataBehavior{HttpGetEnabled = true};
            
            serviceHost.Description.Behaviors.Add(metadataBehavior);
        }

        private static void AddMexEndpoints(ServiceHost serviceHost)
        {
            foreach (var baseAddress in serviceHost.BaseAddresses)
            {
                AddMexEndpoint(serviceHost, baseAddress);                
            }
        }

        private static void AddMexEndpoint(ServiceHost serviceHost, Uri baseAddress)
        {
            BindingElement bindingElement = null;
            switch(baseAddress.Scheme)
            { 
                case "net.tcp":
                    {
                        bindingElement = new TcpTransportBindingElement();                        
                        break;
                    } 
                case "http":
                    {
                        bindingElement = new HttpTransportBindingElement();                        
                        break;
                    }
                case "https":
                    {
                        bindingElement = new HttpsTransportBindingElement();
                        break;
                    }
                case "net.pipe":
                    {
                        bindingElement = new NamedPipeTransportBindingElement();
                        break;
                    }            
            }
            if (bindingElement != null)
            {
                Binding binding = new CustomBinding(bindingElement);
                var endPoint = serviceHost.AddServiceEndpoint(typeof(IMetadataExchange), binding, "MEX");
            }
        }
    }
}
